package mearth;
import processing.core.PApplet;


public class GNode {

	public static int nbrLeaves = 0;
	public static int nbrParents = 0;
	
	int argb;
	int loc, size;
	GNode[] grid;


	public GNode(int loc, int size) {
		super();
		this.loc = loc;
		this.size = size;
		grid = null;
	}

	public GNode(int x, int y, int w, int h) {
		super();
		this.loc = (y << 16) + x;
		this.size = (h << 16) + w;
		grid = null;
	}

	
	public GNode partition(int[] p, int iw){
		int px = (loc & 0xffff);
		int py = (loc >> 16);
		int pw = (size & 0xffff);
		int ph = (size >> 16);
		
		if(pw < 1 && ph < 1)
			return this;
		boolean partitionRequired = false;
		argb = p[py * iw + px]; // color at top left pixel for this partition
		for(int row = 0; row < ph; row++){
			int pn = (py + row) * iw + px;
			for(int col = 0; col < pw; col++){
				// If different colours then we will have to partition
				if(argb != p[pn++]){
					partitionRequired = true;
					break;
				}
			}
			if(partitionRequired)
				break;
		}
		if(partitionRequired){
			int npw0, npw1, nph0, nph1;
			npw1 = pw/2;
			npw0 = pw - npw1;
			nph1 = ph/2;
			nph0 = ph - nph1;
			grid = new GNode[] { null, null, null, null };
			nbrParents ++;
			if(npw1 == 0){
				grid[0] = new GNode(px, py, 1, nph0).partition(p, iw);
				grid[2] = new GNode(px, py+nph0, 1, nph1).partition(p, iw);
				return this;
			}
			if(nph1 == 0){
				grid[0] = new GNode(px, py, npw0, 1).partition(p, iw);
				grid[1] = new GNode(px+npw0, py, npw1, 1).partition(p, iw);
				return this;
			}
			grid[0] = new GNode(px, py, npw0, nph0).partition(p, iw);
			grid[1] = new GNode(px+npw0, py, npw1, nph0).partition(p, iw);
			grid[2] = new GNode(px, py+nph0, npw0, nph1).partition(p, iw);
			grid[3] = new GNode(px+npw0, py+nph0, npw1, nph1).partition(p, iw);
			return this;
		}
		nbrLeaves++;
		return this;
	}


	public void display(PApplet app, float scale){
		if(grid == null) {
			int px = (loc & 0xffff);
			int py = (loc >> 16);
			int pw = (size & 0xffff);
			int ph = (size >> 16);
			app.fill(argb);
			app.rect(px, py, pw, ph);
		}
		else {
			for(int i = 0; i < grid.length; i++)
				if(grid[i] != null){
					grid[i].display(app, scale);
				}
		}

	}

	public String colorToString(int argb){
		int a = (argb & 0xff000000) >> 24;
			int r = (argb & 0xff0000) >> 16;
		int g = (argb & 0xff00) >> 8;
		int b = (argb & 0xff);
		return "[ " + a + " " + r + " " + g + " " + b + " ]";
	}
}
